package com.zhuanzhuan.hero.user.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @ClassName TransactionUtil
 * @Description ring 编程式事务工具类 细分事务颗粒度 避免长事务
 * @Author hanjunjun
 * @Date 2024/7/3 11:23
 */
@Component
@Slf4j
public class TransactionUtil {

    private static PlatformTransactionManager transactionManager;

    @Autowired
    public TransactionUtil(PlatformTransactionManager transactionManager) {
        TransactionUtil.transactionManager = transactionManager;
    }

    /**
     * 没有返回值的
     *
     * @param param
     * @param consumer
     * @return void
     * @author  hanjunjun
     * @date 2024/7/3
     **/
    public static <T> void transactional(T param, Consumer<T> consumer) {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            consumer.accept(param);
            transactionManager.commit(status);
        } catch (Exception e) {
            transactionManager.rollback(status);
            log.error("编程式事务业务异常回滚", e);
        }
    }

    /**
     * 有返回值 一个入参的
     *
     * @param param
     * @param function
     * @return R
     * @author  hanjunjun
     * @date 2024/7/3
     **/
    public static <T, R> R transactional(T param, Function<? super T, ? extends R> function) {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            R apply = function.apply(param);
            transactionManager.commit(status);
            return apply;
        } catch (Exception e) {
            transactionManager.rollback(status);
            log.error("编程式事务业务异常回滚", e);
            return null;
        }
    }

    /**
     * 有返回值  两个入参的
     *
     * @param param
     * @param param2
     * @param function
     * @return R
     * @author  hanjunjun
     * @date 2024/7/3
     **/
    public static <T, U, R> R transactional(T param, U param2, BiFunction<? super T, ? super U, ? extends R> function) {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            R apply = function.apply(param, param2);
            transactionManager.commit(status);
            return apply;
        } catch (Exception e) {
            transactionManager.rollback(status);
            log.error("编程式事务业务异常回滚", e);
            return null;
        }
    }
}
